<?php

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 * Description of ResultModel
 *
 * @author Marko
 */
class Result_model extends CI_Model {

    public function __construct() {
        parent::__construct();
        $this->load->model('Team_model', 'TeamModel');
        $this->load->model('Athlete_model', 'AthleteModel');
        $this->load->model('Event_model', 'EventModel');
        $this->load->model('Fina_model', 'FinaModel');
    }

    public function populate_results_with_data($results, $relays, $events, array $athletes, array $teams, $competition) {

        $populated = array();

        foreach ($results as &$r) {
            $result = new Result();
            foreach ($r AS $key => $value)
                $result->{$key} = $value;

            foreach ($teams as $team) {
                if ($result->team_no == $team['team_no']) {
                    $result->setTeam($team['full_name']);
                    break;
                }
            }

            foreach ($athletes as $athlete) {
                if ($result->ath_no == $athlete['ath_no']) {
                    $result->setAthleteID($this->AthleteModel->athlete_id_from_names_dob($athlete['first_name'], $athlete['last_name'], $athlete['dob']));
                    break;
                }
            }

            $populated[] = $result;
        }
        foreach ($relays as &$r) {
            $result = new Result();
            foreach ($r AS $key => $value)
                $result->{$key} = $value;

            foreach ($teams as $team) {
                if ($result->team_no == $team['team_no']) {
                    $result->setTeam($team['full_name']);
                    break;
                }
            }
            $relay = new Relay($result->relay_team);
            foreach ($athletes as $athlete) {
                for ($pos = 1; $pos <= 4; $pos++) {
                    if (isset($result->{"ath_no$pos"}) && $result->{"ath_no$pos"} == $athlete['ath_no']) {
                        $relay->{"athlete_nr{$pos}_id"} = $this->AthleteModel->athlete_id_from_names_dob($athlete['first_name'], $athlete['last_name'], $athlete['dob']);
                        unset($result->{"ath_no$pos"});
                    }
                }
            }
            $result->setRelay($relay);

            $populated[] = $result;
        }

        $results = $populated;


        foreach ($results as /* @var $result Result */ &$result) {
            foreach ($events as /* @var $event Event */ $event) {
                if ($result->e_id == $event->event_id && $result->e_type == $event->type) {
                    $result->setResultMS($this->Utils->result_float_to_ms($result->result));
                    $result->setSeed($this->Utils->result_float_to_string($result->seed, true));
                    $result->setResult($this->Utils->ms_to_result_string($result->getResultMS()));
                    $this->add_event_data_to_result($result, $event);
                    break;
                }
            }
        }

        return $results;
    }

    public function results_from_mdb_by_event($mdb, Event $e) {
        if (!$e->isRelay()) {
            $query = $mdb->query("SELECT Team_name as team, r.Last_name, r.First_name, Birth_date,
            Switch(r.Res_exh = 'X',1, r.Res_exh = '',0) as exhibition, e.ConvSeed_time as seed, r.Ath_no, 
            r.Res_Time, r.Res_stat " . Utils::generate_split_query($e->getDistance()) . " 
                FROM Athlete, Results AS r, Entries AS e 
                WHERE r.Ath_no=Athlete.Ath_no AND r.Ath_no=e.Ath_no AND r.Relay_ltr=e.Relay_ltr 
                AND r.Team_no = e.Team_no AND r.Event_numltr=e.Event_numltr AND 
                r.Event_numltr = '{$e->getNr()}' AND Cint(r.Event_dist) = {$e->getDistance()} 
                    AND r.Low_age = {$e->getLowAge()} AND r.High_Age = {$e->getHighAge()} AND 
                        r.Event_gender = '{$e->getGender()}' AND NOT Res_stat='NS' 
                            ORDER BY r.Res_Time");
        } else {
            $query = $mdb->query("SELECT  Team_name as team, r.Relay_Ltr as relay_team, 
             Switch(r.Res_exh = 'X',1, r.Res_exh = '',0) as exhibition, e.ConvSeed_time as seed,  
            r.Res_Time, r.Res_stat, r.RelayLeg1_Ath_no, r.RelayLeg2_Ath_no, r.RelayLeg3_Ath_no, 
            r.RelayLeg4_Ath_no" . Utils::generate_split_query($e->getDistance()) . " 
                FROM Results AS r, Entries AS e, Team as t 
                WHERE t.Team_no = r.Team_no AND r.Ath_no=e.Ath_no AND r.Relay_ltr=e.Relay_ltr 
                AND r.Team_no = e.Team_no AND r.Event_numltr=e.Event_numltr AND 
                r.Event_numltr = '{$e->getNr()}' AND Cint(r.Event_dist) = {$e->getDistance()} 
                    AND r.Low_age = {$e->getLowAge()} AND r.High_Age = {$e->getHighAge()} AND 
                        r.Event_gender = '{$e->getGender()}' AND NOT Res_stat='NS' 
                            ORDER BY r.Res_Time");
        }
        $results = $query->result('Result');

        foreach ($results as /* @var $result Result */ &$result) {

            $result->setResultMS($this->Utils->result_float_to_ms($result->Res_Time));
            $result->setSeed($this->Utils->result_float_to_string($result->seed, true));
            $result->setResult($this->Utils->ms_to_result_string($result->getResultMS()));
            $this->add_event_data_to_result($result, $e);
            for ($i = 1; $i <= 30; $i++) {
                if (isset($result->{'Split_' . $i})) {
                    if ($result->{'Split_' . $i} != 0) {
                        $result->splits["Split_$i"] = $this->Utils->result_float_to_ms($result->{'Split_' . $i});
                    }
                } else {
                    break;
                }
            }
            if ($e->isRelay() == 1) {
                $relay = new Relay();
                $relay->setTeam($result->relay_team);
                for ($i = 1; $i <= 4; $i++) {
                    $id = 0;
                    if ($result->{"RelayLeg" . $i . "_Ath_no"} != 0) {
                        $athlete = $mdb->query("SELECT a.Last_name as last_name, a.First_name as first_name, Birth_date as dob FROM Athlete as a WHERE Ath_no={$result->{"RelayLeg" . $i . "_Ath_no"}}")->row(0, 'Athlete');
                        Utils::utf8_encode_deep($athlete);
                        $id = $this->AthleteModel->athlete_id_from_names_dob($athlete->getFirstName(), $athlete->getLastName(), date('Y-m-d', strtotime($athlete->getDob())));
                    }
                    switch ($i) {
                        case 1:
                            $relay->setAthleteOneID($id);
                            break;
                        case 2:
                            $relay->setAthleteTwoID($id);
                            break;
                        case 3:
                            $relay->setAthleteThreeID($id);
                            break;
                        case 4:
                            $relay->setAthleteFourID($id);
                            break;
                        default:
                            break;
                    }
                }
                $result->setRelay($relay);
            } else {
                $result->setAthleteID($this->AthleteModel->athlete_id_from_names_dob(utf8_encode($result->First_name), utf8_encode($result->Last_name), date('Y-m-d', strtotime($result->Birth_date))));
                if ($result->getAthleteID() == 0) {
                    print_r($result->First_name . ' - ' . $result->Last_name . ' - ' . $result->Birth_date);
                }
            }
        }
        Utils::trim_deep($results);
        Utils::utf8_encode_deep($results);
        return $results;
    }

    function result_exists($result, $event_id) {
        $result = mysql_query("SELECT COUNT(`id`) FROM `results` WHERE `result`='$result' and `event_id`=$event_id ") or die(mysql_error());
        return mysql_result($result, 0) == 1;
    }

    function insert_relay_to_db(Relay $relay) {
        $query = "INSERT INTO `relays`(`team`, `athlete_nr1_id`, `athlete_nr2_id`, `athlete_nr3_id`, `athlete_nr4_id`) VALUES ";

        $fields = '(\'' . implode('\', \'', $relay->toArray()) . '\')';

        $query .= $fields;
//echo $query;
        mysql_query($query) or die(mysql_error());
        return mysql_insert_id();
    }

    function count_results($id) {
        $result = mysql_query("SELECT COUNT(`id`) FROM `results` WHERE `competition_id`=$id ") or die(mysql_error());
        return mysql_result($result, 0);
    }

    function relay_from_id($id) {
        $result = mysql_query("SELECT `id`, `team`, `athlete_nr1_id`, `athlete_nr2_id`, `athlete_nr3_id`, `athlete_nr4_id` FROM `relays` WHERE `id`=$id");
        return mysql_fetch_assoc($result);
    }

    function add_data_to_results($results, $events) {
        foreach ($results as $event_nr => &$results_of_event) {
            $event = $events[$event_nr];
            if ($event['relay'] == 0) {
                foreach ($results_of_event as &$result) {
                    if (strpos($result['result'], 'DQ') !== false) {
                        $result['result'] = 0;
                    }
                    $result['distance'] = $event['distance'];
                    $result['stroke'] = $event['stroke'];
                    $result['athlete_id'] = athlete_id_from_name_age($result['first_name'], $result['last_name'], null);
                }
            }
        }

        unset($results_of_event);
        unset($result);

        return $results;
    }

    function athlete_id_from_relay_name($name) {
        if ($name != NULL) {
            $name = preg_replace("/[^a-ü ,-]+/i", '', $name);
            $name = preg_replace("/( M| W)$/i", '', $name);
            $name = preg_replace("/^ /", '', $name);
        }
        $names = explode(', ', $name);
        $id = 0;
        if (count($names) > 1) {
            $id = $this->AthleteModel->athlete_id_from_name_age($names[1], $names[0], null);
        }
        return $id;
    }

    function parse_Result_from_xml($data) {
        if (!empty($data)) {
            $i = 0;
            $result = new Result();
            $relay_team = NULL;
            do {
                if (empty($data->FormattedAreaPair[0]->FormattedArea[0]
                                ->FormattedSections[0]->FormattedSection[0]
                                ->FormattedReportObjects[0])) {
                    break;
                }
                $object = $data->FormattedAreaPair[0]->FormattedArea[0]
                        ->FormattedSections[0]->FormattedSection[0]
                        ->FormattedReportObjects[0]
                        ->FormattedReportObject[$i];
                if (empty($object)) {
                    break;
                };
                $result_val = $object->ObjectName;
                switch ($result_val) {
                    case 'teamrelay1':
                        $result->setTeam(strval($object->Value));
                        break;
                    case 'age1':
                        $result->setAthleteAge(strval($object->Value));
                        break;
                    case 'Rank1':
//not used at the moment
                        break;
                    case 'athrelname1':
                        $names = explode(', ', strval($object->Value));
                        if (count($names) > 1 && $this->TeamModel->team_from_full_name(strval($object->Value)) == null) {
                            $result->setAthleteID($this->AthleteModel->athlete_id_from_name_age($names[1], $names[0], null));
                            if ($result->getAthleteID() == 0) {
                                $result->setAthleteName(strval($object->Value));
                            }
                        } else {
                            $relay_team = strval($object->Value);
                        }
                        break;
                    case 'timefield21':
                        $result->setResult(strval($object->Value));
                        $result->setResultMS($this->Utils->result_to_ms($result->getResult()));
                        break;
                    case 'timefield11':
                        $result->setSeed(strval($object->Value));
                        break;
                    default:
                        break;
                }
                $i++;
            } while ($i < 20);
            if ($relay_team == NULL)
                return $result;
            $i = 0;
            $relay = new Relay($result->getTeam());
            $result->setTeam($relay_team);
            do {
                if (empty($data->FormattedAreaPair[0]->FormattedArea[0]
                                ->FormattedSections[0]->FormattedSection[1])) {
                    break;
// was not a relay
                }
                $object = $data->FormattedAreaPair[0]->FormattedArea[0]
                        ->FormattedSections[0]->FormattedSection[1]
                        ->FormattedReportObjects[0]
                        ->FormattedReportObject[$i];
                if (empty($object)) {
                    break;
                };
                $result_val = $object->ObjectName;
                switch ($result_val) {
                    case 'relayname11':
                        $name = strval($object->Value);
                        $relay->setAthleteOneID($this->athlete_id_from_relay_name($name));
                        break;
                    case 'relayname21':
                        $name = strval($object->Value);
                        $relay->setAthleteTwoID($this->athlete_id_from_relay_name($name));
                        break;
                    case 'relayname31':
                        $name = strval($object->Value);
                        $relay->setAthleteThreeID($this->athlete_id_from_relay_name($name));
                        break;
                    case 'relayname41':
                        $name = strval($object->Value);
                        $relay->setAthleteFourID($this->athlete_id_from_relay_name($name));
                        break;
                    default:
                        break;
                }
                $i++;
            } while ($i < 20);
            $result->setRelay($relay);
            return $result;
        }
        return null;
    }

    function results_events_from_xml_path($path_to_xml, $competition_id) {
        $results_xml = simplexml_load_file($path_to_xml);

        $competition = Competition::fromID($competition_id);
        $j = 0;
        $results = array();
        $events = array();
        echo '<br>';
        $current_event = null;
        do {
            $data = $results_xml->FormattedAreaPair[0]->FormattedAreaPair[$j];
            $event = $this->EventModel->parse_Event_from_xml($data);
            if ($event != null) {
                $current_event = $event;
                $event->setCompetitionID($competition_id);
                $event->setFinaBaseTime($competition->getPool(), $competition->getStartDate());
                $events[] = $event;
            }
            $result = $this->parse_Result_from_xml($data);
            if ($result != null) {
                $result->setCompetitionID($competition_id);
                $this->add_event_data_to_result($result, $current_event);

                $results[] = $result;
            }

            $j++;
        } while (!empty($data) && $j < 10000);

        return array('results' => $results, 'events' => $events);
    }

    /**
     * Populates Result with Event data (distance, stroke, fina, date and eventRaw)
     * @param Result $result
     * @param Event $event
     * @return Result
     */
    function add_event_data_to_result(Result &$result, Event $event) {
        $result->setDistance($event->getDistance());
        $result->setStroke($event->getStroke());
        $result->setEventRaw($event->getRaw());
        $result->setDate($event->getDate());
        $result->setCompetitionID($event->getCompetitionID());
        $result->setFina($this->FinaModel->fina_points_for_result($event->getFinaBaseTime(), $result->getResultMS()));
    }

    /**
     * Populates Result with fina points calculated using Event, Result and Competition data.
     * @param Result $r
     * @param Event $e
     * @param Competition $c
     * @return Result
     */
    function add_fina_points_to_result(Result $r, Event $e, Competition $c) {
        $fina = (int) fina_points_for_result($r->getResultMS(), date('Y', strtotime($c->getStartDate())), $c->getPool(), $e->getGender(), $e->isRelay(), $r->getDistance(), $r->getStroke());
        $r->setFina($fina);
        return $r;
    }
    
    public function insertResultsRelaysSplits($results) {
        $event_id = 0;
        $last_event_raw = '';
        foreach ($results as /* @var $result Result */ &$result) {
            if ($last_event_raw != $result->getEventRaw()) {
                $event_id = $this->EventModel->event_id_from_raw_competition($result->getEventRaw(), $result->getCompetitionID());
                $last_event_raw = $result->getEventRaw();
            }
            if ($result->getRelay() != NULL) {
                $this->db->insert('relays', $result->getRelay());
                $result->setRelayID($this->db->insert_id());
            } else {
                $result->setRelayID(0);
            }
            if (isset($result->splits) && count($result->splits) != 0) {
                foreach($result->splits as $key => $value) {
                    $key++;
                    $result->splits["split_$key"] = $result->splits[$key-1] * 1000.0;
                    unset($result->splits[$key-1]);
                }
                $result->splits['id'] = null;
                $this->db->insert('splits', $result->splits);
                $result->setSplitID($this->db->insert_id());
            } else {
                $result->setSplitID(0);
            }

            $result->setEventID($event_id);

            unset($result->splits);
            unset($result->athleteAge);
            unset($result->athleteName);
            unset($result->relay);
            unset($result->eventRaw);
            unset($result->e_id);
            unset($result->e_type);
            unset($result->team_no);
            unset($result->ath_no);
            unset($result->relay_team);
            $this->db->insert('results', $result);
        }
    }

    function insert_results_to_db($results) {
        $query = "INSERT INTO `results`(`result`, `result_ms`, `distance`, `stroke`, `team`, 
         `seed`, `fina`, `athlete_id`, `relay_id`, `event_id`, `competition_id`, `date`) VALUES ";
        $fields = '';
        foreach ($results as /* @var $result Result */ $result) {

            if ($result->getRelay() != NULL) {
                $result->setRelayID($this->insert_relay_to_db($result->getRelay()));
            }
            $result->setEventID($this->EventModel->event_id_from_raw_competition($result->getEventRaw(), $result->getCompetitionID()));
            $fields .= '(\'' . implode('\', \'', $result->toArray()) . '\'), ';
        }
        $fields = substr($fields, 0, strlen($fields) - 2);

        $query .= $fields;
//        echo $query;
        mysql_query($query) or die(mysql_error());
    }

}

?>
